# add -DDEBUG_MEM to turn on memory allocation logging
-CFLAGS=-g -Icoldsync
+CFLAGS=$(EXTRA_CFLAGS) -g -Icoldsync
INSTALL_TARGETDIR=/usr/local/
FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o \
gpsutil.o pcx.o cetus.o gpspilot.o magnav.o \
psp.o holux.o garmin.o tmpro.o tpg.o \
- xcsv.o xmapwpt.o gcdb.o internal_styles.o
+ xcsv.o gcdb.o internal_styles.o
FILTERS=position.o duplicate.o
# Nerdy release stuff that needs to work only on Linux.
+leaktest:
+ make EXTRA_CFLAGS=-DDEBUG_MEM
+ leaks/cleardebug
+ ./testo
+ leaks/memdebug | grep -v '^command line:'
+
internal_styles.c: mkstyle.sh
./mkstyle.sh > internal_styles.c
position.o:position.c defs.h
waypt.o: waypt.c defs.h queue.h
xcsv.o: xcsv.c defs.h queue.h csv_util.h
-xmapwpt.o: xmapwpt.c defs.h queue.h csv_util.h
coldsync/pdb.o: coldsync/pdb.c coldsync/config.h coldsync/pdb.h
coldsync/util.o: coldsync/util.c coldsync/config.h
jeeps/gpsapp.o: jeeps/gpsapp.c jeeps/gps.h jeeps/gpsport.h \
#define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0)
#define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0)
-static void *mkshort_handle;
-
/*********************************************************************/
/* csv_stringclean() - remove any unwanted characters from string. */
/* returns copy of string. */
*/
xcsv_file.ofield = xcalloc(sizeof(queue), 1);
QUEUE_INIT(xcsv_file.ofield);
+
+ xcsv_file.mkshort_handle = mkshort_new_handle();
}
/*****************************************************************************/
int i;
field_map_t *fmp;
queue *elem, *tmp;
-
+
if (wpt->shortname) {
- anyname = mkshort(mkshort_handle, wpt->shortname);
+ anyname = xstrdup(wpt->shortname);
} else
if (wpt->description) {
- anyname = mkshort(mkshort_handle, wpt->description);
+ anyname = mkshort(xcsv_file.mkshort_handle, wpt->description);
} else
if (wpt->notes) {
anyname = xstrdup(wpt->notes);
- } else
+ } else
anyname = xstrdup("");
-
+
if ((anyname) && (global_opts.synthesize_shortnames)) {
char *oldname = anyname;
- anyname = mkshort(mkshort_handle, oldname);
+ anyname = mkshort(xcsv_file.mkshort_handle, oldname);
xfree(oldname);
}
if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) {
if (wpt->description) {
if (global_opts.synthesize_shortnames)
- shortname = mkshort(mkshort_handle, wpt->description);
+ shortname = mkshort(xcsv_file.mkshort_handle, wpt->description);
else
shortname = csv_stringclean(wpt->description, xcsv_file.badchars);
} else {
{
queue *elem, *tmp;
ogue_t *ogp;
- mkshort_handle = mkshort_new_handle();
/* output prologue lines, if any. */
QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) {
ogp = (ogue_t *) elem;
fprintf (xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter);
}
- mkshort_del_handle(mkshort_handle);
}
FILE * xcsvfp; /* ptr to current *open* data file */
char * description; /* Description for help text */
- int shortlen; /* preferred shortname length */
char * extension; /* preferred filename extension (for wrappers)*/
+ void * mkshort_handle; /* handle for mkshort() */
+
} xcsv_file_t;
"#\n"
"DESCRIPTION GPSman\n"
+"SHORTLEN 8\n"
+"SHORTWHITE 0\n"
"# FILE LAYOUT DEFINITIIONS:\n"
"#\n"
"DESCRIPTION OziExplorer Waypoint\n"
"EXTENSION ozi\n"
+"SHORTLEN 14\n"
"#\n"
"# FILE LAYOUT DEFINITIIONS:\n"
"IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n"
"IFIELD DESCRIPTION, \"\", \"%s\"\n"
;
+static char xmapwpt[] =
+"# gpsbabel XCSV style file\n"
+"#\n"
+"# Format: Delorme Xmap HH Street Atlas USA .WPT (PocketPC)\n"
+"# Author: Alex Mottram\n"
+"# Date: 12/09/2002\n"
+"#\n"
+"# \n"
+"DESCRIPTION Delorme XMat HH Street Atlas USA .WPT (PPC)\n"
+"SHORTLEN 32\n"
+"SHORTWHITE 0\n"
+
+"#\n"
+"#\n"
+"# FILE LAYOUT DEFINITIIONS:\n"
+"#\n"
+"FIELD_DELIMITER COLON\n"
+"RECORD_DELIMITER NEWLINE\n"
+"BADCHARS COLON\n"
+
+"#\n"
+"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n"
+"#\n"
+"IFIELD CONSTANT, \"1296126539\", \"%s\"\n"
+"IFIELD CONSTANT, \"1481466224\", \"%s\"\n"
+"IFIELD LAT_INT32DEG, \"\", \"%d\"\n"
+"IFIELD LON_INT32DEG, \"\", \"%d\"\n"
+"IFIELD CONSTANT, \"3137157\", \"%s\"\n"
+"IFIELD SHORTNAME, \"\", \"%-.31s\"\n"
+"IFIELD IGNORE, \"\", \"%-.31s\"\n"
+"IFIELD DESCRIPTION, \"\", \"%-.78s\"\n"
+;
#include "defs.h"
-style_vecs_t style_list[] = {{ "xmap", xmap } , { "tiger", tiger } , { "s_and_t", s_and_t } , { "ozi", ozi } , { "nima", nima } , { "mxf", mxf } , { "gpsman", gpsman } , { "gpsdrive", gpsdrive } , { "dna", dna } , { "custom", custom } , { "csv", csv } , {0,0}};
+style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap", xmap } , { "tiger", tiger } , { "s_and_t", s_and_t } , { "ozi", ozi } , { "nima", nima } , { "mxf", mxf } , { "gpsman", gpsman } , { "gpsdrive", gpsdrive } , { "dna", dna } , { "custom", custom } , { "csv", csv } , {0,0}};
INTERNAL CONSTANTS:
A few internal constants are defined in the XCSV parser to make the style
-file simpler. They may or may be used and are optional in most cases.
+file simpler. They may or may not be used and are optional in most cases.
Note that only certain style file directives map these constants.
STYLE CONSTANT MAPS TO CHAR(s)
This directive gives the filename extension generally associated with
this file.
+GPSBABEL BEHAVIOR DIRECTIVES:
+-----------------------------
+There are a few available directives to 'control' some of the internal
+processing functions of GPSbabel.
+
+ o SHORTLEN:
+
+ This sets the maximum allowed shortname length when using the internal
+ shortname synthesizer.
+
+ example:
+ SHORTLEN 16 # shortnames will be at most 16 characters long.
+
+
+ o SHORTWHITE:
+
+ This tells the shortname synthesizer whether or not not allow whitespace
+ in the synthesized shortnames. Allowed values are zero and one.
+
+ example:
+ SHORTWHITE 0 # Do not allow whitespace in shortname.
+ SHORTWHITE 1 # Allow whitespace in shortname.
+
+
DEFINING THE LAYOUT OF THE FILE:
--------------------------------
The first few directives define the layout the physical file itself:
EXAMPLES:
--------
For examples on using the XCSV module, please see the *.style files in
-the style/ subdirectory of gpsbabel. For examples of using the XCSV
-module instead of carving out trivial C code, see the source code
-examples ozi.c, mxf.c, and xmapwpt.c in the gpsbabel directory.
+the style/ subdirectory of gpsbabel.
#
DESCRIPTION GPSman
+SHORTLEN 8
+SHORTWHITE 0
# FILE LAYOUT DEFINITIIONS:
#
DESCRIPTION OziExplorer Waypoint
EXTENSION ozi
+SHORTLEN 14
#
# FILE LAYOUT DEFINITIIONS:
vfprintf( debug_mem_file, format, args );
fflush( debug_mem_file );
}
- va_end( format );
+ va_end( args );
}
void
extern ff_vecs_t xcsv_vecs;
extern ff_vecs_t tpg_vecs;
extern ff_vecs_t magnav_vec;
-extern ff_vecs_t xmapwpt_vecs;
extern ff_vecs_t tmpro_vecs;
extern ff_vecs_t gcdb_vecs;
"gpsutil",
NULL
},
- {
- &xmapwpt_vecs,
- "xmapwpt",
- "Delorme XMap HH Native .WPT",
- ".wpt"
- },
{
&psp_vecs,
"psp",
}
xcsv_read_internal_style(svec->style_buf);
+ xfree(v);
+
return vec_list[0].vec;
}
#define MYNAME "XCSV"
#define ISSTOKEN(a,b) (strncmp(a,b, strlen(b)) == 0)
-static void *mkshort_handle;
+static char *styleopt;
+static char *snlenopt;
+static char *snwhiteopt;
+static char *snupperopt;
+
+static
+arglist_t xcsv_args[] = {
+ {"style", &styleopt, "Full path to XCSV style file (required)"},
+ {"snlen", &snlenopt, "Max synthesized shortname length"},
+ {"snwhite", &snwhiteopt, "(0/1) Allow whitespace synth. shortnames"},
+ {"snupper", &snupperopt, "(0/1) UPPERCASE synth. shortnames"},
+ {0, 0, 0}
+};
/* a table of config file constants mapped to chars */
static
/* destroy the prologue */
QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) {
- if (xcsv_file.is_internal == 0) {
- ogp = (ogue_t *)elem;
- if (ogp->val)
- xfree(ogp->val);
- }
+ ogp = (ogue_t *)elem;
+ if (ogp->val)
+ xfree(ogp->val);
if (elem)
xfree(elem);
}
/* destroy the epilogue */
QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) {
- if (xcsv_file.is_internal == 0) {
- ogp = (ogue_t *)elem;
- if (ogp->val)
- xfree(ogp->val);
- }
+ ogp = (ogue_t *)elem;
+ if (ogp->val)
+ xfree(ogp->val);
if (elem)
xfree(elem);
}
/* destroy the ifields */
QUEUE_FOR_EACH(&xcsv_file.ifield, elem, tmp) {
- if (xcsv_file.is_internal == 0) {
- fmp = (field_map_t *) elem;
- if (fmp->key)
- xfree(fmp->key);
- if (fmp->val)
- xfree(fmp->val);
- if (fmp->printfc)
- xfree(fmp->printfc);
- }
+ fmp = (field_map_t *) elem;
+ if (fmp->key)
+ xfree(fmp->key);
+ if (fmp->val)
+ xfree(fmp->val);
+ if (fmp->printfc)
+ xfree(fmp->printfc);
if (elem)
xfree(elem);
}
/* destroy the ofields, if they are not re-mapped to ifields. */
if (xcsv_file.ofield != &xcsv_file.ifield) {
QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) {
- if (xcsv_file.is_internal == 0) {
- fmp = (field_map_t *) elem;
- if (fmp->key)
- xfree(fmp->key);
- if (fmp->val)
- xfree(fmp->val);
- if (fmp->printfc)
- xfree(fmp->printfc);
- }
+ fmp = (field_map_t *) elem;
+ if (fmp->key)
+ xfree(fmp->key);
+ if (fmp->val)
+ xfree(fmp->val);
+ if (fmp->printfc)
+ xfree(fmp->printfc);
if (elem)
xfree(elem);
}
xfree(xcsv_file.ofield);
}
- if (xcsv_file.is_internal == 0) {
- /* other alloc'd glory */
- if (xcsv_file.field_delimiter)
- xfree(xcsv_file.field_delimiter);
+ /* other alloc'd glory */
+ if (xcsv_file.field_delimiter)
+ xfree(xcsv_file.field_delimiter);
- if (xcsv_file.record_delimiter)
- xfree(xcsv_file.record_delimiter);
+ if (xcsv_file.record_delimiter)
+ xfree(xcsv_file.record_delimiter);
- if (xcsv_file.badchars)
- xfree(xcsv_file.badchars);
- }
+ if (xcsv_file.badchars)
+ xfree(xcsv_file.badchars);
+
+ if (xcsv_file.description)
+ xfree(xcsv_file.description);
+
+ if (xcsv_file.extension)
+ xfree(xcsv_file.extension);
+
+ if (xcsv_file.mkshort_handle)
+ xfree(xcsv_file.mkshort_handle);
/* return everything to zeros */
memset(&xcsv_file, '\0', sizeof(xcsv_file));
} else
if (ISSTOKEN(sbuff, "SHORTLEN")) {
- xcsv_file.shortlen = atoi(&sbuff[9]);
+ if (xcsv_file.mkshort_handle)
+ setshort_length(xcsv_file.mkshort_handle, atoi(&sbuff[9]));
+ } else
+
+ if (ISSTOKEN(sbuff, "SHORTWHITE")) {
+ if (xcsv_file.mkshort_handle)
+ setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(&sbuff[12]));
} else
if (ISSTOKEN(sbuff, "BADCHARS")) {
{
xcsv_file_init();
xcsv_file.is_internal = 1;
+
xcsv_parse_style_buff(style_buf);
/* if we have no output fields, use input fields as output fields */
static void
xcsv_rd_init(const char *fname, const char *args)
{
- char *p;
/*
* if we don't have an internal style defined, we need to
* read it from a user-supplied style file, or die trying.
*/
if (xcsv_file.is_internal == 0) {
- p = get_option(args, "style");
-
- if (!p)
+ if (!styleopt)
fatal(MYNAME ": XCSV input style not declared. Use ... -i xcsv,style=path/to/file.style\n");
- xcsv_read_style(p);
- xfree(p);
+ xcsv_read_style(styleopt);
}
xcsv_file.xcsvfp = fopen(fname, "r");
static void
xcsv_wr_init(const char *fname, const char *args)
{
- char * p;
- mkshort_handle = mkshort_new_handle();
-
/* if we don't have an internal style defined, we need to
* read it from a user-supplied style file, or die trying.
*/
if (xcsv_file.is_internal == 0) {
- p = get_option(args, "style");
- if (!p)
+ if (!styleopt)
fatal(MYNAME ": XCSV output style not declared. Use ... -o xcsv,style=path/to/file.style\n");
- xcsv_read_style(p);
- xfree(p);
-
- /* set mkshort options from the command line */
- if (global_opts.synthesize_shortnames) {
- p = get_option(args, "snlen");
- if (p) {
- setshort_length(mkshort_handle, atoi(p));
- xfree(p);
- }
-
- p = get_option(args, "snwhite");
- if (p) {
- setshort_whitespace_ok(mkshort_handle, atoi(p));
- xfree(p);
- }
-
- p = get_option(args, "snupper");
- if (p) {
- setshort_mustupper(mkshort_handle, atoi(p));
- xfree(p);
- }
-
- setshort_badchars(mkshort_handle, xcsv_file.badchars);
- }
+ xcsv_read_style(styleopt);
}
xcsv_file.xcsvfp = fopen(fname, "w");
if (xcsv_file.xcsvfp == NULL)
fatal(MYNAME ": Cannot open %s for writing\n", fname);
+
+ /* set mkshort options from the command line */
+ if (global_opts.synthesize_shortnames) {
+
+ if (snlenopt)
+ setshort_length(xcsv_file.mkshort_handle, atoi(snlenopt));
+
+ if (snwhiteopt)
+ setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(snwhiteopt));
+
+ if (snupperopt)
+ setshort_mustupper(xcsv_file.mkshort_handle, atoi(snupperopt));
+
+ setshort_badchars(xcsv_file.mkshort_handle, xcsv_file.badchars);
+
+ }
+
}
static void
fclose(xcsv_file.xcsvfp);
xcsv_destroy_style();
- mkshort_del_handle(mkshort_handle);
}
ff_vecs_t xcsv_vecs = {
xcsv_wr_deinit,
xcsv_data_read,
xcsv_data_write,
+ xcsv_args
};
-/*
- Delorme XMap HandHeld .WPT Format
- (as created by XMapHH Street Atlas/PPC)
- 1296126539:1481466224:1895825408:1392508928:3137157:text:text:text\n
-
- Contributed to gpsbabel by Alex Mottram (geo_alexm at cox-internet.com)
-
- Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
-
- */
-
-#include "defs.h"
-#include "csv_util.h"
-
-#define MYNAME "XMAPWPT"
-static void *mkshort_handle= NULL;
-
-static void
-xmapwpt_set_style()
-{
- /* set up the xmapwpt xcsv_file struct */
- xcsv_file_init();
-
- /* this is an internal style, don't mess with it */
- xcsv_file.is_internal = 1;
-
- /* how the file gets split up */
- xcsv_file.field_delimiter = ":";
- xcsv_file.record_delimiter = "\n";
- xcsv_file.badchars = ":";
-
- xcsv_ifield_add("CONSTANT", "1296126539", "%s");
- xcsv_ifield_add("CONSTANT", "1481466224", "%s");
- xcsv_ifield_add("LAT_INT32DEG", "", "%d");
- xcsv_ifield_add("LON_INT32DEG", "", "%d");
- xcsv_ifield_add("CONSTANT", "3137157", "%s");
- xcsv_ifield_add("SHORTNAME", "", "%-.31s");
- xcsv_ifield_add("IGNORE", "", "%-.31s");
-
- /*
- * actual description len accepted is 79. however under win32, we
- * run the risk of the compiled app ending a line in \r\n when we
- * say \n. This, in turn, overruns a fixed len buffer and causes
- * XmapHH to die both occasionally and horribly.
- */
- xcsv_ifield_add("DESCRIPTION", "", "%-.78s");
-
- /* outfields are infields */
- if (xcsv_file.ofield)
- xfree(xcsv_file.ofield);
- xcsv_file.ofield = &xcsv_file.ifield;
- xcsv_file.ofield_ct = xcsv_file.ifield_ct;
-
- /* set up mkshort */
- if (global_opts.synthesize_shortnames) {
- setshort_length(mkshort_handle, 32);
- setshort_whitespace_ok(mkshort_handle, 0);
- setshort_badchars(mkshort_handle, xcsv_file.badchars);
- }
-}
-
-static void
-xmapwpt_rd_init(const char *fname, const char *args)
-{
- xmapwpt_set_style();
-
- xcsv_file.xcsvfp = fopen(fname, "r");
-
- if (xcsv_file.xcsvfp == NULL) {
- fatal(MYNAME ": Cannot open %s for reading\n", fname );
- }
-}
-
-static void
-xmapwpt_wr_init(const char *fname, const char *args)
-{
- mkshort_handle = mkshort_new_handle();
-
- xmapwpt_set_style();
-
- xcsv_file.xcsvfp = fopen(fname, "w");
-
- if (xcsv_file.xcsvfp == NULL) {
- fatal(MYNAME ": Cannot open %s for reading\n", fname );
- }
-}
-
-static void
-xmapwpt_deinit(void)
-{
- if (xcsv_file.xcsvfp)
- fclose(xcsv_file.xcsvfp);
-
- xcsv_destroy_style();
- if ( mkshort_handle )
- mkshort_del_handle(mkshort_handle);
- mkshort_handle = NULL;
-}
-
-ff_vecs_t xmapwpt_vecs = {
- xmapwpt_rd_init,
- xmapwpt_wr_init,
- xmapwpt_deinit,
- xmapwpt_deinit,
- xcsv_data_read,
- xcsv_data_write,
-};